<template>
  <div class="page-wrap">
    <a-card title="用户管理" :bordered="false">
      <template #extra>
        <a-space>
          <a-input v-model="query.username" placeholder="用户名" allow-clear style="width: 160px" />
          <a-input v-model="query.phone" placeholder="手机号" allow-clear style="width: 160px" />
          <a-button type="primary" @click="fetchList">查询</a-button>
          <a-button @click="resetQuery">重置</a-button>
          <a-button type="primary" status="success" @click="openEdit()">新增</a-button>
        </a-space>
      </template>

      <a-alert v-if="lastError" type="error" closable :content="lastError" style="margin-bottom: 12px;" />
      <a-empty v-else-if="!loading && rows.length === 0" description="暂无数据" style="margin-bottom: 12px;" />
      <a-table
          row-key="userId"
          :data="rows"
          :columns="columns"
          :loading="loading"
          :pagination="{
            current: pagination.current,
            pageSize: pagination.pageSize,
            total: pagination.total,
            showTotal: true
          }"
          @page-change="onPageChange"
          @page-size-change="onPageSizeChange"
      />

      <!-- 新增/编辑 -->
      <a-modal v-model:visible="editVisible" :title="editing?.userId ? '编辑用户' : '新增用户'" :mask-closable="false" @ok="saveUser" :confirm-loading="saving">
        <a-form :model="editing" layout="vertical">
          <a-form-item field="username" label="用户名" :rules="[{ required: true, message: '请输入用户名' }]">
            <a-input v-model="editing.username" />
          </a-form-item>
          <a-form-item field="name" label="姓名">
            <a-input v-model="editing.name" />
          </a-form-item>
          <a-form-item field="phone" label="手机号">
            <a-input v-model="editing.phone" />
          </a-form-item>
          <a-form-item field="email" label="邮箱">
            <a-input v-model="editing.email" />
          </a-form-item>
        </a-form>
      </a-modal>

      <!-- 分配角色 -->
      <a-modal v-model:visible="assignVisible" title="分配角色" :mask-closable="false" @ok="submitAssignRoles" :confirm-loading="assignSaving">
        <a-spin :loading="assignLoading">
          <a-checkbox-group v-model="checkedRoleIds" :options="roleOptions" />
          <div v-if="!roleOptions.length" style="color:#999;">暂无角色数据</div>
        </a-spin>
      </a-modal>
    </a-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { Message } from '@arco-design/web-vue';
import type { SysUser } from '@/types/system';
import { userList, userAdd, userUpdate, userDelete, userResetPassword, userAssignRoles, userGet } from '@/api/user';
import { roleList } from '@/api/role';

// 将后端下划线 key 统一转为驼峰，避免表格 data-index 匹配不到字段
function snakeToCamel<T extends Record<string, any>>(obj: T): T {
  if (!obj || typeof obj !== 'object') return obj as T;
  const out: any = {};
  Object.keys(obj).forEach((k) => {
    const camel = k.replace(/_([a-z])/g, (_, p1) => p1.toUpperCase());
    out[camel] = (obj as any)[k];
  });
  return out;
}
function normalizeList<T = any>(arr: any[]): T[] {
  return Array.isArray(arr) ? arr.map((x) => (x && typeof x === 'object' ? snakeToCamel(x) : x)) : [];
}

// 适配用户表格需要的关键字段，避免列名不匹配导致不显示
function adaptUser<T extends Record<string, any>>(y: T): T {
  if (!y || typeof y !== 'object') return y as T;
  const userId = (y as any).userId ?? (y as any).id ?? (y as any).user_uid ?? (y as any).userID ?? (y as any).userUid;
  const username = (y as any).username ?? (y as any).userName ?? (y as any).account;
  const name = (y as any).name ?? (y as any).nickName ?? (y as any).realName ?? (y as any).nickname;
  const phone = (y as any).phone ?? (y as any).mobile ?? (y as any).tel ?? (y as any).telephone;
  const email = (y as any).email ?? (y as any).mail;
  return {
    ...y,
    userId,
    username,
    name,
    phone,
    email,
  } as T;
}

const query = reactive<{ username?: string; phone?: string; pageNo: number; pageSize: number }>({
  username: '',
  phone: '',
  pageNo: 1,
  pageSize: 10,
});

const loading = ref(false);
const rows = ref<SysUser[]>([]);
const lastError = ref<string>('');
const pagination = reactive({
  current: 1,
  pageSize: 10,
  total: 0,
  showTotal: true,
});

// 使用 columns 属性定义表格列
const columns = [
  {
    title: '用户ID',
    dataIndex: 'userId',
    width: 100,
  },
  {
    title: '用户名',
    dataIndex: 'username',
  },
  {
    title: '姓名',
    dataIndex: 'name',
  },
  {
    title: '手机号',
    dataIndex: 'phone',
  },
  {
    title: '邮箱',
    dataIndex: 'email',
  },
  {
    title: '操作',
    width: 320,
    // render: (_, record) => {
    //     return (
    //         <a-space>
    //         <a-button type="text" onClick={() => openEdit(record)}>编辑</a-button>
    //     <a-button type="text" status="warning" onClick={() => openAssignRoles(record)}>分配角色</a-button>
    //     <a-popconfirm content="确认重置该用户密码？" onOk={() => onResetPassword(record)}>
    //     <a-button type="text">重置密码</a-button>
    //         </a-popconfirm>
    //         <a-popconfirm content="确认删除该用户？" onOk={() => onDelete(record)}>
    //     <a-button type="text" status="danger">删除</a-button>
    //         </a-popconfirm>
    //         </a-space>
    //   );
    //   },
  },
];

function onPageChange(p: number) {
  pagination.current = p;
  query.pageNo = p;
  fetchList();
}
function onPageSizeChange(ps: number) {
  pagination.pageSize = ps;
  query.pageSize = ps;
  fetchList();
}

async function fetchList() {
  loading.value = true;
  try {
    lastError.value = '';
    const res = await userList(query as any);

    if (res) {
      const pageData: any = (res as any)?.data ?? res;
      console.log('pageData', pageData);

      if (Array.isArray(pageData.items)) {
        rows.value = normalizeList(pageData.items).map(adaptUser);
        pagination.total = Number(pageData.total ?? pageData.items.length ?? 0);
        pagination.current = Number(pageData.pageNum ?? query.pageNo);
        pagination.pageSize = Number(pageData.pageSize ?? query.pageSize);
      } else if (Array.isArray(pageData.records)) {
        rows.value = normalizeList(pageData.records).map(adaptUser);
        pagination.total = Number(pageData.total ?? pageData.records.length ?? 0);
        pagination.current = Number(pageData.current ?? query.pageNo);
        pagination.pageSize = Number(pageData.size ?? query.pageSize);
      } else if (Array.isArray(pageData.list)) {
        rows.value = normalizeList(pageData.list).map(adaptUser);
        pagination.total = Number(pageData.total ?? pageData.list.length ?? 0);
      } else if (Array.isArray(pageData)) {
        rows.value = normalizeList(pageData).map(adaptUser);
        pagination.total = pageData.length;
      } else {
        rows.value = [];
        pagination.total = 0;
      }
    } else {
      rows.value = [];
      pagination.total = 0;
      lastError.value = '服务无返回数据';
    }
  } catch (err: any) {
    const status = err?.response?.status;
    const msg = err?.response?.data?.message || err?.message || '加载失败';
    if (status === 401) {
      Message.error('未登录或登录已过期');
    } else if (status === 403) {
      Message.error('无权查看用户列表（缺少 system:user:list 权限）');
    } else {
      Message.error(msg);
    }
    lastError.value = `请求失败(${status || '异常'}): ${msg}`;
    rows.value = [];
    pagination.total = 0;
  } finally {
    loading.value = false;
  }
}
function resetQuery() {
  query.username = '';
  query.phone = '';
  query.pageNo = 1;
  pagination.current = 1;
  fetchList();
}

const editVisible = ref(false);
const saving = ref(false);
const editing = reactive<Partial<SysUser>>({
  username: '',
  name: '',
  phone: '',
  email: ''
});

function openEdit(row?: SysUser) {
  editVisible.value = true;
  Object.assign(editing, { userId: undefined, username: '', name: '', phone: '', email: '' });
  if (row?.userId) Object.assign(editing, row);
}
async function saveUser() {
  saving.value = true;
  try {
    if (editing.userId) {
      await userUpdate(editing as any);
      Message.success('已保存');
    } else {
      await userAdd(editing as any);
      Message.success('已新增');
    }
    editVisible.value = false;
    await fetchList();
  } finally {
    saving.value = false;
  }
}

async function onDelete(row: SysUser) {
  await userDelete(row.userId);
  Message.success('已删除');
  fetchList();
}

async function onResetPassword(row: SysUser) {
  await userResetPassword(row.userId);
  Message.success('已重置密码');
}

// 分配角色
const assignVisible = ref(false);
const assignLoading = ref(false);
const assignSaving = ref(false);
const currentUserId = ref<number | null>(null);
const roleOptions = ref<{ label: string; value: number }[]>([]);
const checkedRoleIds = ref<number[]>([]);

async function openAssignRoles(row: SysUser) {
  currentUserId.value = row.userId;
  assignVisible.value = true;
  assignLoading.value = true;
  try {
    const rl = await roleList();
    roleOptions.value = (rl.data || []).map((r: any) => ({ label: `${r.roleName || r.roleCode} (${r.roleId})`, value: r.roleId }));

    // 预选
    try {
      const u = await userGet(row.userId);
      const ids: number[] =
          (u.data as any)?.roleIdList ??
          ((u.data as any)?.roles?.map((x: any) => x.roleId) ?? []);
      checkedRoleIds.value = Array.isArray(ids) ? ids : [];
    } catch {
      checkedRoleIds.value = [];
    }
  } finally {
    assignLoading.value = false;
  }
}

async function submitAssignRoles() {
  if (!currentUserId.value) return;
  assignSaving.value = true;
  try {
    await userAssignRoles(currentUserId.value, checkedRoleIds.value);
    Message.success('已分配角色');
    assignVisible.value = false;
  } finally {
    assignSaving.value = false;
  }
}

onMounted(fetchList);
</script>

<style scoped>
.page-wrap { padding: 12px; }
</style>
